<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="16">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span></span>
          </div>
          <el-row :gutter="20">
            <el-col :span="6">
              <div class="data-card">
                <div class="card-title">今日告警</div>
                <div class="card-value">{{ alarmStatistics.today_count }}</div>
                <div class="card-desc">
                  较昨日 
                  <span :class="alarmStatistics.growth_rate > 0 ? 'text-danger' : 'text-success'">
                    {{ alarmStatistics.growth_rate > 0 ? '+' : '' }}{{ alarmStatistics.growth_rate }}%
                  </span>
                </div>
              </div>
            </el-col>
            <el-col :span="18">
              <div id="alarmTrendChart" style="width: 100%; height: 100px;"></div>
            </el-col>
          </el-row>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>告警类型分布</span>
          </div>
          <div id="alarmTypeChart" style="width: 100%; height: 100px;"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" style="margin-top: 20px">
      <el-col :span="12">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>告警设备TOP5</span>
          </div>
          <div id="deviceAlarmChart" style="width: 100%; height: 300px;"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>告警类型TOP5</span>
          </div>
          <div id="dataTypeAlarmChart" style="width: 100%; height: 300px;"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-card class="box-card" style="margin-top: 20px">
      <div slot="header" class="clearfix">
        <span>告警列表</span>
        <div class="filter-container">
          <el-input
            v-model="listQuery.device_name"
            placeholder="设备名称"
            style="width: 150px;"
            class="filter-item"
            size="small"
            @keyup.enter.native="handleFilter"
          />
          <el-select
            v-model="listQuery.group_id"
            placeholder="设备组"
            clearable
            size="small"
            style="width: 150px"
            class="filter-item"
          >
            <el-option v-for="item in groupOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-select
            v-model="listQuery.data_type"
            placeholder="数据类型"
            clearable
            size="small"
            style="width: 120px"
            class="filter-item"
          >
            <el-option v-for="item in dataTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-select
            v-model="listQuery.alarm_type"
            placeholder="告警类型"
            clearable
            size="small"
            style="width: 120px"
            class="filter-item"
          >
            <el-option v-for="item in alarmTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            align="right"
            size="small"
            unlink-panels
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :picker-options="pickerOptions"
            class="filter-item"
            style="width: 240px"
          />
          <el-button class="filter-item" type="primary" icon="el-icon-search" size="small" @click="handleFilter">搜索</el-button>
          <el-button class="filter-item" type="success" icon="el-icon-refresh" size="small" @click="handleReset">重置</el-button>
        </div>
      </div>

      <el-table
        v-loading="listLoading"
        :data="list"
        element-loading-text="正在加载..."
        border
        fit
        highlight-current-row
        size="small"
      >
        <el-table-column label="序号" align="center" width="60">
          <template #default="{ row }">
            {{ (listQuery.page - 1) * listQuery.pageSize + scope.$index + 1 }}
          </template>
        </el-table-column>
        <el-table-column label="设备名称" prop="device.name" align="center" min-width="120" show-overflow-tooltip />
        <el-table-column label="数据类型" prop="data_type" align="center" width="100" show-overflow-tooltip />
        <el-table-column label="数据值" prop="data_value" align="center" width="100" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" align="center" width="80" show-overflow-tooltip />
        <el-table-column label="告警类型" align="center" width="100">
          <template #default="{ row }">
            <el-tag :type="getAlarmTypeTag(row.alarm_type)">
              {{ getAlarmTypeText(row.alarm_type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="告警阈值" prop="alarm_threshold" align="center" width="100" show-overflow-tooltip />
        <el-table-column label="告警时间" prop="data_time" align="center" width="150" show-overflow-tooltip />
        <el-table-column label="处理状态" align="center" width="100">
          <template #default="{ row }">
            <el-tag :type="getProcessStatusTag(row.process_status || 0)">
              {{ getProcessStatusText(row.process_status || 0) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="handleDetail(row)">详情</el-button>
            <el-button 
              v-if="row.process_status === 0" 
              type="success" 
              size="small" 
              @click="handleProcess(row)"
            >处理</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-show="total>0"
        :total="total"
        :page.sync="listQuery.page"
        :limit.sync="listQuery.pageSize"
        @pagination="getList"
      />
    </el-card>

    <!-- 告警详情对话框 -->
    <el-dialog title="告警详情" v-model="detailDialogVisible" width="800px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="设备名称">{{ currentAlarm.device ? currentAlarm.device.name : '' }}</el-descriptions-item>
        <el-descriptions-item label="数据类型">{{ currentAlarm.data_type }}</el-descriptions-item>
        <el-descriptions-item label="数据值">{{ currentAlarm.data_value }}</el-descriptions-item>
        <el-descriptions-item label="单位">{{ currentAlarm.unit }}</el-descriptions-item>
        <el-descriptions-item label="告警类型">
          <el-tag :type="getAlarmTypeTag(currentAlarm.alarm_type)">
            {{ getAlarmTypeText(currentAlarm.alarm_type) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="告警阈值">{{ currentAlarm.alarm_threshold }}</el-descriptions-item>
        <el-descriptions-item label="告警时间">{{ currentAlarm.data_time }}</el-descriptions-item>
        <el-descriptions-item label="处理状态">
          <el-tag :type="getProcessStatusTag(currentAlarm.process_status || 0)">
            {{ getProcessStatusText(currentAlarm.process_status || 0) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="处理时间" :span="2">{{ currentAlarm.process_time || '未处理' }}</el-descriptions-item>
        <el-descriptions-item label="处理备注" :span="2">{{ currentAlarm.process_remark || '无' }}</el-descriptions-item>
      </el-descriptions>

      <div style="margin-top: 20px">
        <div class="section-title">相同设备历史告警</div>
        <el-table
          :data="currentAlarm.history || []"
          border
          fit
          highlight-current-row
          size="small"
        >
          <el-table-column label="数据类型" prop="data_type" align="center" />
          <el-table-column label="数据值" prop="data_value" align="center" />
          <el-table-column label="告警类型" align="center">
            <template #default="{ row }">
              <el-tag :type="getAlarmTypeTag(row.alarm_type)">
                {{ getAlarmTypeText(row.alarm_type) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="告警时间" prop="data_time" align="center" />
        </el-table>
      </div>

      <div style="margin-top: 20px">
        <div class="section-title">上下文数据</div>
        <div id="contextChart" style="width: 100%; height: 200px;"></div>
      </div>
      
      <span slot="footer" class="dialog-footer">
        <el-button @click="detailDialogVisible = false">关闭</el-button>
        <el-button v-if="currentAlarm.process_status === 0" type="primary" @click="handleProcess(currentAlarm)">处理告警</el-button>
      </span>
    </el-dialog>

    <!-- 告警处理对话框 -->
    <el-dialog title="告警处理" v-model="processDialogVisible" width="500px">
      <el-form ref="processForm" :model="processForm" label-width="80px">
        <el-form-item label="处理方式">
          // 在告警处理对话框部分修改
          <el-radio-group v-model="processForm.status">
            <el-radio :value="1">已确认</el-radio>
            <el-radio :value="2">已处理</el-radio>
            <el-radio :value="3">已忽略</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="处理备注">
          <el-input type="textarea" v-model="processForm.remark" :rows="4" placeholder="请输入处理备注"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="processDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitProcess">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import { getAlarmList, getAlarmStatistics, getAlarmDetail, processAlarm } from '@/api/data'
import { getDeviceGroupTree } from '@/api/device'
import Pagination from '@/components/Pagination'

export default {
  name: 'AlarmManagement',
  components: { Pagination },
  data() {
    return {
      // 表格数据
      list: [],
      total: 0,
      listLoading: true,
      
      // 查询条件
      listQuery: {
        page: 1,
        pageSize: 10,
        device_name: '',
        group_id: '',
        data_type: '',
        alarm_type: ''
      },
      dateRange: [],
      
      // 告警统计数据
      alarmStatistics: {
        today_count: 0,
        yesterday_count: 0,
        growth_rate: 0,
        type_stats: [],
        device_top: [],
        data_type_top: [],
        trend: []
      },
      
      // 图表实例
      alarmTrendChart: null,
      alarmTypeChart: null,
      deviceAlarmChart: null,
      dataTypeAlarmChart: null,
      contextChart: null,
      
      // 选项数据
      dataTypeOptions: [
        { value: 'temperature', label: '温度' },
        { value: 'humidity', label: '湿度' },
        { value: 'pressure', label: '压力' },
        { value: 'flow', label: '流量' },
        { value: 'level', label: '液位' }
      ],
      alarmTypeOptions: [
        { value: 1, label: '超出上限' },
        { value: 2, label: '低于下限' },
        { value: 3, label: '数据异常' },
        { value: 4, label: '连接断开' },
        { value: 5, label: '其他' }
      ],
      groupOptions: [],
      
      // 日期选择器配置
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }]
      },
      
      // 详情对话框
      detailDialogVisible: false,
      currentAlarm: {},
      
      // 处理对话框
      processDialogVisible: false,
      processForm: {
        id: null,
        status: 1,
        remark: ''
      }
    }
  },
  created() {
    this.getList()
    this.fetchAlarmStatistics()
    this.fetchDeviceGroups()
  },
  mounted() {
    this.initCharts()
    
    // 监听窗口大小变化，调整图表大小
    window.addEventListener('resize', this.resizeCharts)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeCharts)
    
    // 销毁图表实例
    this.alarmTrendChart && this.alarmTrendChart.dispose()
    this.alarmTypeChart && this.alarmTypeChart.dispose()
    this.deviceAlarmChart && this.deviceAlarmChart.dispose()
    this.dataTypeAlarmChart && this.dataTypeAlarmChart.dispose()
    this.contextChart && this.contextChart.dispose()
  },
  methods: {
    // 初始化所有图表
    initCharts() {
      this.alarmTrendChart = echarts.init(document.getElementById('alarmTrendChart'))
      this.alarmTypeChart = echarts.init(document.getElementById('alarmTypeChart'))
      this.deviceAlarmChart = echarts.init(document.getElementById('deviceAlarmChart'))
      this.dataTypeAlarmChart = echarts.init(document.getElementById('dataTypeAlarmChart'))
    },
    
    // 调整图表大小
    resizeCharts() {
      this.alarmTrendChart && this.alarmTrendChart.resize()
      this.alarmTypeChart && this.alarmTypeChart.resize()
      this.deviceAlarmChart && this.deviceAlarmChart.resize()
      this.dataTypeAlarmChart && this.dataTypeAlarmChart.resize()
      this.contextChart && this.contextChart.resize()
    },
    
    // 获取设备组选项
    fetchDeviceGroups() {
      getDeviceGroupTree().then(response => {
        if (response.code === 200) {
          this.groupOptions = this.formatGroupOptions(response.data)
        }
      })
    },
    
    // 格式化设备组选项
    formatGroupOptions(data, prefix = '') {
      let options = []
      data.forEach(item => {
        options.push({
          value: item.id,
          label: prefix + item.name
        })
        if (item.children && item.children.length > 0) {
          options = options.concat(this.formatGroupOptions(item.children, prefix + '-- '))
        }
      })
      return options
    },
    
    // 获取告警列表
    getList() {
      this.listLoading = true
      
      const params = { ...this.listQuery }
      
      if (this.dateRange && this.dateRange.length === 2) {
        params.start_time = this.formatDate(this.dateRange[0])
        params.end_time = this.formatDate(this.dateRange[1])
      }
      
      getAlarmList(params).then(response => {
        if (response.code === 200) {
          this.list = response.data.data
          this.total = response.data.total
        }
        this.listLoading = false
      }).catch(() => {
        this.listLoading = false
      })
    },
    
    // 获取告警统计
    fetchAlarmStatistics() {
      getAlarmStatistics().then(response => {
        if (response.code === 200) {
          this.alarmStatistics = response.data
          
          // 更新告警趋势图
          this.updateAlarmTrendChart()
          
          // 更新告警类型分布图
          this.updateAlarmTypeChart()
          
          // 更新设备告警排行图
          this.updateDeviceAlarmChart()
          
          // 更新数据类型告警排行图
          this.updateDataTypeAlarmChart()
        }
      })
    },
    
    // 更新告警趋势图
    updateAlarmTrendChart() {
      const trend = this.alarmStatistics.trend
      this.alarmTrendChart.setOption({
        tooltip: {
          trigger: 'axis'
        },
        grid: {
          top: 5,
          right: 10,
          bottom: 5,
          left: 40,
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: trend.map(item => item.date),
          axisLine: {
            show: false
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          type: 'value',
          axisLine: {
            show: false
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            name: '告警数',
            type: 'line',
            smooth: true,
            data: trend.map(item => item.count),
            areaStyle: {},
            itemStyle: {
              color: '#F56C6C'
            }
          }
        ]
      })
    },
    
    // 更新告警类型分布图
    updateAlarmTypeChart() {
      const typeStats = this.alarmStatistics.type_stats
      this.alarmTypeChart.setOption({
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        grid: {
          top: 5,
          right: 10,
          bottom: 5,
          left: 10,
          containLabel: true
        },
        series: [
          {
            name: '告警类型',
            type: 'pie',
            radius: ['50%', '70%'],
            avoidLabelOverlap: false,
            label: {
              show: false
            },
            labelLine: {
              show: false
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
            data: typeStats.map(item => {
              return { 
                value: item.count, 
                name: this.getAlarmTypeText(item.alarm_type)
              }
            })
          }
        ]
      })
    },
    
    // 更新设备告警排行图
    updateDeviceAlarmChart() {
      const deviceTop = this.alarmStatistics.device_top
      this.deviceAlarmChart.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'value',
          boundaryGap: [0, 0.01]
        },
        yAxis: {
          type: 'category',
          data: deviceTop.map(item => item.name)
        },
        series: [
          {
            name: '告警数量',
            type: 'bar',
            data: deviceTop.map(item => item.count),
            itemStyle: {
              color: '#F56C6C'
            }
          }
        ]
      })
    },
    
    // 更新数据类型告警排行图
    updateDataTypeAlarmChart() {
      const dataTypeTop = this.alarmStatistics.data_type_top
      this.dataTypeAlarmChart.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'value',
          boundaryGap: [0, 0.01]
        },
        yAxis: {
          type: 'category',
          data: dataTypeTop.map(item => item.data_type)
        },
        series: [
          {
            name: '告警数量',
            type: 'bar',
            data: dataTypeTop.map(item => item.count),
            itemStyle: {
              color: '#F56C6C'
            }
          }
        ]
      })
    },
    
    // 获取详细信息
    handleDetail(row) {
      getAlarmDetail(row.id).then(response => {
        if (response.code === 200) {
          this.currentAlarm = response.data
          this.detailDialogVisible = true
          
          // 在下一次DOM更新后初始化上下文数据图表
          this.$nextTick(() => {
            if (this.contextChart) {
              this.contextChart.dispose()
            }
            this.contextChart = echarts.init(document.getElementById('contextChart'))
            this.updateContextChart()
          })
        }
      })
    },
    
    // 更新上下文数据图表
    updateContextChart() {
      const contextData = this.currentAlarm.context || []
      // 添加当前告警数据
      const allData = [...contextData, {
        data_time: this.currentAlarm.data_time,
        data_value: this.currentAlarm.data_value,
        is_current: true
      }].sort((a, b) => new Date(a.data_time) - new Date(b.data_time))
      
      this.contextChart.setOption({
        tooltip: {
          trigger: 'axis',
          formatter: function(params) {
            const data = params[0].data
            return `时间：${data.time}<br/>数值：${data.value}`
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: allData.map(item => {
            const date = new Date(item.data_time)
            return date.getHours() + ':' + date.getMinutes().toString().padStart(2, '0')
          })
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            type: 'line',
            data: allData.map(item => {
              return {
                value: item.data_value,
                time: item.data_time,
                // 当前告警点使用不同样式
                itemStyle: item.is_current ? {
                  color: '#F56C6C',
                  borderWidth: 5
                } : {}
              }
            }),
            markPoint: {
              data: allData.filter(item => item.is_current).map(() => ({
                type: 'max',
                name: '告警点'
              }))
            }
          }
        ]
      })
    },
    
    // 处理告警
    handleProcess(row) {
      this.processForm = {
        id: row.id,
        status: 1,
        remark: ''
      }
      this.processDialogVisible = true
    },
    
    // 提交处理结果
    submitProcess() {
      processAlarm(this.processForm).then(response => {
        if (response.code === 200) {
          this.$message.success('处理成功')
          this.processDialogVisible = false
          this.detailDialogVisible = false
          this.getList()
        }
      })
    },
    
    // 处理筛选
    handleFilter() {
      this.listQuery.page = 1
      this.getList()
    },
    
    // 重置筛选条件
    handleReset() {
      this.listQuery = {
        page: 1,
        pageSize: 10,
        device_name: '',
        group_id: '',
        data_type: '',
        alarm_type: ''
      }
      this.dateRange = []
      this.getList()
    },
    
    // 获取告警类型文本
    getAlarmTypeText(type) {
      const types = {
        1: '超出上限',
        2: '低于下限',
        3: '数据异常',
        4: '连接断开',
        5: '其他'
      }
      return types[type] || '未知'
    },
    
    // 获取告警类型标签类型
    getAlarmTypeTag(type) {
      const tags = {
        1: 'danger',
        2: 'warning',
        3: 'info',
        4: 'info',
        5: ''
      }
      return tags[type] || ''
    },
    
    // 获取处理状态文本
    getProcessStatusText(status) {
      const statuses = {
        0: '未处理',
        1: '已确认',
        2: '已处理',
        3: '已忽略'
      }
      return statuses[status] || '未知'
    },
    
    // 获取处理状态标签类型
    getProcessStatusTag(status) {
      const tags = {
        0: 'danger',
        1: 'warning',
        2: 'success',
        3: 'info'
      }
      return tags[status] || ''
    },
    
    // 格式化日期
    formatDate(date) {
      const year = date.getFullYear()
      const month = (date.getMonth() + 1).toString().padStart(2, '0')
      const day = date.getDate().toString().padStart(2, '0')
      return `${year}-${month}-${day}`
    }
  }
}
</script>

<style scoped>
.data-card {
  padding: 15px;
  text-align: center;
  height: 100px;
  background-color: #f5f7fa;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.card-title {
  font-size: 14px;
  color: #909399;
  margin-bottom: 10px;
}

.card-value {
  font-size: 24px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 5px;
}

.card-desc {
  font-size: 12px;
  color: #606266;
}

.text-danger {
  color: #F56C6C;
}

.text-success {
  color: #67C23A;
}

.filter-container {
  float: right;
  margin-top: -5px;
}

.filter-item {
  margin-right: 10px;
}

.section-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 10px;
  padding-left: 10px;
  border-left: 3px solid #409EFF;
}
</style> 